/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package managedBean.TX.tta;

import session.TX.TTADisplaySBRemote;
import Helper.TTAHelper.Helper_PIPSales;
import Helper.TTAHelper.Helper_PIPSalesPred;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.event.ActionEvent;
import org.primefaces.component.chart.series.ChartSeries;
import org.primefaces.model.chart.CartesianChartModel;

/**
 *
 * @author Lu Xiaodi
 */
@ManagedBean(name = "tCubePIPSalesMB")
@ViewScoped
public class TCubePIPSalesMB {

    @EJB
    TTADisplaySBRemote pipBean;
    private Calendar start;
    private Calendar end;
    private List<Calendar> possibleMonths;
    private Set<Integer> startMonths = new HashSet<Integer>();
    private List<Integer> startYears = new ArrayList<Integer>();
    private List<Integer> endYears = new ArrayList<Integer>();
    private Set<Integer> endMonths = new HashSet<Integer>();
    private Integer salesYearStart;
    private Integer salesMonthStart;
    private Integer salesYearEnd;
    private Integer salesMonthEnd;
    private Integer numMonthToPred = 3;
    private Integer numHistoricalMonths = 12;
    
    private double saleCorCoef;
    private Helper_PIPSalesPred predItem;
    private NumberFormat formatter;
    
    public TCubePIPSalesMB(){
        formatter = new DecimalFormat("#0.0000");
    }

    public CartesianChartModel getSalesModel() {
        possibleMonths = this.getPossibleMonths();
        if (possibleMonths == null || possibleMonths.isEmpty()){
            return new CartesianChartModel();
        }
        if (start == null || end == null) {
            start = possibleMonths.get(0);
            end = possibleMonths.get(possibleMonths.size() - 1);
        }
        List<Helper_PIPSales> returnList = pipBean.getTCubeSalesData(start, end);
        CartesianChartModel model = new CartesianChartModel();
        if (returnList == null || returnList.isEmpty()) {
            return model;
        }
        ChartSeries sales = new ChartSeries("Sales");
        for (int i = 0; i < returnList.size(); i++) {
            Helper_PIPSales aHelper = returnList.get(i);
            sales.set(aHelper.getTimeStr(), aHelper.getRevenue());
        }
        model.addSeries(sales);
        return model;
    }

    public CartesianChartModel getSalesWithPredModel() {
        if (predItem == null) {
            this.updatePrediction();
            if (predItem == null) {
                return new CartesianChartModel();
            }
        }
        List<Helper_PIPSales> returnList = predItem.getModel();
        CartesianChartModel model = new CartesianChartModel();
        if (returnList == null || returnList.isEmpty()) {
            return model;
        }
        ChartSeries sales = new ChartSeries("Sales");
        ChartSeries preds = new ChartSeries("Pred");
        for (int i = 0; i < returnList.size() - numMonthToPred; i++) {
            Helper_PIPSales aHelper = returnList.get(i);
            sales.set(aHelper.getTimeStr(), aHelper.getRevenue());
        }
        for (int j = returnList.size() - numMonthToPred; j < returnList.size(); j++) {
            Helper_PIPSales aHelper = returnList.get(j);
            preds.set(aHelper.getTimeStr(), aHelper.getRevenue());
        }
        model.addSeries(sales);
        model.addSeries(preds);
        return model;
    }
    
    public void updatePrediction() {
        System.out.println("num historical months:" + numHistoricalMonths);
        possibleMonths = this.getPossibleMonths();
        if (possibleMonths == null || possibleMonths.isEmpty()) {
            return;
        }
        Calendar predStart;
        Calendar predEnd;
        if (possibleMonths == null || possibleMonths.isEmpty()) {
            return;
        }
        if (possibleMonths.size() <= numHistoricalMonths) {
            predStart = possibleMonths.get(0);
        } else {
            predStart = possibleMonths.get(possibleMonths.size() - numHistoricalMonths - 1);
        }
        predEnd = possibleMonths.get(possibleMonths.size() - 1);
        predItem = pipBean.getSalesDataWithPred(predStart, predEnd, numMonthToPred);
        if (predItem != null) {
            saleCorCoef = predItem.getCorcoef();
        }
    }

    public Calendar getEnd() {
        return end;
    }

    public void setEnd(Calendar end) {
        this.end = end;
    }

    public Calendar getStart() {
        return start;
    }

    public void setStart(Calendar start) {
        this.start = start;
    }

    public Integer getSalesMonthStart() {
        return salesMonthStart;
    }

    public void setSalesMonthStart(Integer salesMonth) {
        this.salesMonthStart = salesMonth;
    }

    public Integer getSalesYearStart() {
        return salesYearStart;
    }

    public void setSalesYearStart(Integer salesYear) {
        this.salesYearStart = salesYear;
    }

    public Integer getSalesMonthEnd() {
        return salesMonthEnd;
    }

    public void setSalesMonthEnd(Integer salesMonthEnd) {
        this.salesMonthEnd = salesMonthEnd;
    }

    public Integer getSalesYearEnd() {
        return salesYearEnd;
    }

    public void setSalesYearEnd(Integer salesYearEnd) {
        this.salesYearEnd = salesYearEnd;
    }

    public List<Calendar> getPossibleMonths() {
        if (this.possibleMonths == null) {
            possibleMonths = pipBean.getTCubeAvailableMonths();
        }
        return possibleMonths;
    }

    public List<Integer> getStartYears() {
        if (this.startYears == null || this.startYears.isEmpty()) {
            startYears = new ArrayList<Integer>();
            Set temp = new HashSet<Integer>();
            List<Calendar> timeList = this.getPossibleMonths();
            for (Calendar c : timeList) {
                temp.add(c.get(Calendar.YEAR));
            }
            for (Object t : temp) {
                startYears.add((Integer) t);
            }
        }
        Collections.sort(startYears, new Comparator<Integer>() {

            public int compare(Integer i1, Integer i2) {
                if (i1 - i2 > 0) {
                    return 1;
                } else if (i1 - i2 < 0) {
                    return -1;
                } else {
                    return 0;
                }
            }
        });
        return startYears;
    }

    public List<Integer> getEndYears() {
        if (this.endYears == null || this.endYears.isEmpty()) {
            endYears = new ArrayList<Integer>();
            Set temp = new HashSet<Integer>();
            List<Calendar> timeList = this.getPossibleMonths();
            for (Calendar c : timeList) {
                temp.add(c.get(Calendar.YEAR));
            }
            for (Object t : temp) {
                endYears.add((Integer) t);
            }
        }
        Collections.sort(endYears, new Comparator<Integer>() {

            public int compare(Integer i1, Integer i2) {
                if (i1 - i2 > 0) {
                    return 1;
                } else if (i1 - i2 < 0) {
                    return -1;
                } else {
                    return 0;
                }
            }
        });
        return endYears;
    }

    public void handleStartYearChange() {
        startMonths = new HashSet<Integer>();
        if (salesYearStart != null) {
            for (Calendar c : this.getPossibleMonths()) {
                if (c.get(Calendar.YEAR) == salesYearStart.intValue()) {
                    startMonths.add(c.get(Calendar.MONTH) + 1);
                }
            }
        }
    }

    public void handleEndYearChange() {
        endMonths = new HashSet<Integer>();
        if (salesYearEnd != null) {
            for (Calendar c : this.getPossibleMonths()) {
                if (c.get(Calendar.YEAR) == salesYearEnd.intValue()) {
                    endMonths.add(c.get(Calendar.MONTH) + 1);
                }
            }
        }
    }

    public Set<Integer> getStartMonths() {
        return startMonths;
    }

    public Set<Integer> getEndMonths() {
        return endMonths;
    }

    public void updateStartEnd(ActionEvent event) {
        start = Calendar.getInstance();
        start.set(salesYearStart, salesMonthStart - 1, 1, 0, 0, 0);
        end = Calendar.getInstance();
        end.set(salesYearEnd, salesMonthEnd - 1, 1, 0, 0, 0);
    }

    public Integer getNumMonthToPred() {
        return numMonthToPred;
    }

    public void setNumMonthToPred(Integer numMonthToPred) {
        this.numMonthToPred = numMonthToPred;
    }

    public Integer getNumHistoricalMonths() {
        return numHistoricalMonths;
    }

    public void setNumHistoricalMonths(Integer numHistoricalMonths) {
        this.numHistoricalMonths = numHistoricalMonths;
    }

    public void updateNumMonthToPred(ActionEvent event) {
    }

    public double getSaleCorCoef() {
        if ((saleCorCoef-0)<0.00001){
            updatePrediction();
        }
        return saleCorCoef;
    }

    public void setSaleCorCoef(double saleCorCoef) {
        this.saleCorCoef = saleCorCoef;
    }
    
    public String getSaleCorCoefStr(){
        double corr = this.getSaleCorCoef();
        return formatter.format(corr);
    }
}
